package com.songtech.uitest.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.CellType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.InputStream;
import java.lang.reflect.Method;


/**
 * 读取外部.xls格式的配置文件。
 * 工程默认是读取application.properties为配置文件的，只能记录一条单的流程信息。
 * 在有多个单的流程配置时，这个类用于读取资源文件夹customConfigFlows里的流程配置文件。
 */
@Component
public class ConfigLoader {

    @Autowired
    private JarPathHelper jarPathHelper;

    private Logger logger = LoggerFactory.getLogger(ConfigLoader.class);


    public void loadFromFile(String fileName) {
        InputStream in = null;
        HSSFWorkbook workbook = null;
        logger.info("开始读取外部配置文件" + fileName);
        try {
            in = jarPathHelper.getRootPathStreamInJar("customFlows/" + fileName);
            workbook = new HSSFWorkbook(in);

            HSSFSheet sheet = workbook.getSheetAt(0);

            //设置Excel单元格格式
            HSSFCellStyle cellStyle = workbook.createCellStyle();
            HSSFDataFormat format = workbook.createDataFormat();
            cellStyle.setDataFormat(format.getFormat("@"));

            for (int i = 0; i <= sheet.getLastRowNum(); i++) {
                HSSFRow row = sheet.getRow(i);
                HSSFCell key = row.getCell(0);
                HSSFCell value = row.getCell(1);
                value.setCellType(CellType.STRING);//杜绝将1读为1.0


                if (key == null || key.getStringCellValue().equals("")) {
                    continue;
                } //跳过为空的行
                if (key.toString().substring(0, 1).equals("#")) {
                    continue;
                } //以#开头的行为注释，跳过

                //得到的key类似：indent.propose
                String prefix = StringUtils.substringBeforeLast(key.toString(), ".");
                String propertyName = StringUtils.substringAfterLast(key.toString(), ".");
                switch (prefix) {
                    case "system":
                        setResFileProperty("SystemResource", propertyName, value.getStringCellValue());
                        break;
                    case "server":
                        setResFileProperty("ServerResource", propertyName, value.getStringCellValue());
                        break;
                    case "assist":
                        setResFileProperty("AssistResource", propertyName, value.getStringCellValue());
                        break;
                    case "third":
                        setResFileProperty("ThirdResource", propertyName, value.getStringCellValue());
                        break;
                    case "indent":
                        setResFileProperty("IndentResource", propertyName, value.getStringCellValue());
                        break;

                }
                logger.info("读取参数" + key + "=" + value.getStringCellValue());

            }
            logger.info("外部配置文件" + fileName + "读取完毕。");

        }catch (Exception e){
            logger.error("读取外部配置文件" + fileName + "失败。错误信息如下：" + e.toString());
            e.printStackTrace();
        }

        try {
            workbook.close();
            in.close();
        }
        catch (Exception e){
            e.printStackTrace();
        }


    }


    public void setResFileProperty(String resFileName, String propertyName, String value) throws Exception{
        //得到对象
        String resObjName = Character.toLowerCase(resFileName.charAt(0)) + resFileName.substring(1);
        Object resObject = SpringUtil.getBean(resObjName);
        //得到setter方法名
        String methodName = "set" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
        //得到Object[]类型的参数
        Object[] paramsArray = new Object[]{value};
        //得到Class[]类型的参数
        Class[] paramsClass = new Class[]{String.class};

        //得到setter方法
        Method method = resObject.getClass().getMethod(methodName, paramsClass);

        //调用setter方法
        method.invoke(resObject, paramsArray);

    }



}
